package com.atguigu.gmall.item.controller;

import com.atguigu.gmall.common.result.Result;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@Slf4j
@RestController
public class RedissonController {
    @Autowired
    RedissonClient redissonClient;

    //可重入锁
    @GetMapping("/redisson/lock")
    public Result lock() {
        //获取一把锁
        RLock lock = redissonClient.getLock("0623-lock");

        try {//加锁及操作业务放在 try里面，就算业务有异常炸了也没事
            //阻塞式加锁； 一定要等到锁。  得到锁：锁的默认时间30s
            //lock.lock();
            //阻塞式加锁(传了锁释放时间)； 一定要等到锁。  得到锁：锁的默认时间40s，而且没有续期功能；
            lock.lock(40, TimeUnit.SECONDS);


            //尝试加锁：试一下； true：加锁成功；  默认时间30s; 自动续期
            //boolean tryLock = lock.tryLock();
            //尝试加锁：10s内一直尝试。 true: 加锁成功(10s内返回true)  false：10s以后一定返回的是false   默认时间30s
            boolean tryLock = lock.tryLock(10, TimeUnit.SECONDS);
            //尝试加锁：10s内一直尝试。 true：加锁成功锁就20s有效 不续期
            //boolean tryLock = lock.tryLock(10, 20, TimeUnit.SECONDS);
            if (tryLock){
                log.info("执行业务");
                TimeUnit.SECONDS.sleep(60);
            }else {
                log.info("加锁失败");
            }


        } catch (Exception e) {
            //e.printStackTrace();  //吃掉异常
        } finally {
            try {//解锁可能出现问题，放在try里面：比如锁已经没了，然后再去执行解锁操作
                //解锁
                log.info("解锁完成。。。");
                lock.unlock();//同步解锁； 万一发现不是自己的锁，就不用解锁。
                //lock.unlockAsync();//异步解锁
            }catch (Exception e){} // 吃掉异常
        }

        return Result.ok();
    }

    @GetMapping("/redisson/client")
    public Result client() {
        log.info("redissonClient:{}" + redissonClient);
        return Result.ok();
    }
}
